package org.catpay.modules.sys.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.catpay.common.exception.RRException;
import org.catpay.common.utils.Constant;
import org.catpay.common.utils.PageUtils;
import org.catpay.common.utils.Query;
import org.catpay.modules.sys.dao.SysUserDao;
import org.catpay.modules.sys.entity.SysRoleEntity;
import org.catpay.modules.sys.entity.SysUserEntity;
import org.catpay.modules.sys.service.SysRoleService;
import org.catpay.modules.sys.service.SysUserRoleService;
import org.catpay.modules.sys.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import cn.hutool.core.collection.CollectionUtil;


/**
 * 系统用户
 * 
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
	
	@Autowired
	private SysUserRoleService sysUserRoleService;
	
	@Autowired
	private SysRoleService sysRoleService;
	

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		String username = MapUtils.getString(params, "username");
		Page<SysUserEntity> page = this.selectPage(
			new Query<SysUserEntity>(params).getPage(),
			new EntityWrapper<SysUserEntity>()
				.like(StringUtils.isNotBlank(username),"username", username)
				/*.eq(createUserId != null,"create_user_id", createUserId)*/
		);
		
		return new PageUtils(page);
	}
	
	@Override
	public List<String> queryAllPerms(Long userId) {
		return baseMapper.queryAllPerms(userId);
	}

	@Override
	public List<Long> queryAllMenuId(Long userId) {
		return baseMapper.queryAllMenuId(userId);
	}

	@Override
	public SysUserEntity queryByUserName(String username) {
		return  this.selectOne(new EntityWrapper<SysUserEntity>().eq("username", username));
	}

	@Override
	@Transactional
	public void save(SysUserEntity user) {
		
		setRole(user);
		
		user.setCreateTime(new Date());
		//sha256加密
		String salt = RandomStringUtils.randomAlphanumeric(20);
		user.setPassword(new Sha256Hash(user.getPassword(), salt,1024).toHex());
		user.setSalt(salt);
		this.insert(user);
		
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	@Transactional
	public void update(SysUserEntity user) {
		
		setRole(user);
		this.updateById(user);
		//保存用户与角色关系
		sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
	}

	@Override
	public void deleteBatch(Long[] userId) {
		this.deleteBatchIds(Arrays.asList(userId));
	}

	@Override
	public boolean updatePassword(Long userId, String password, String newPassword) {
		SysUserEntity userEntity = new SysUserEntity();
		userEntity.setPassword(newPassword);
		return this.update(userEntity,
				new EntityWrapper<SysUserEntity>().eq("user_id", userId).eq("password", password));
	}
	
	/**
	 * 检查角色是否越权
	 */
	private void setRole(SysUserEntity user){
		
		if(CollectionUtil.isNotEmpty(user.getRoleIdList())) {
			List<SysRoleEntity> list = sysRoleService.selectBatchIds(user.getRoleIdList());
			if(list.size() != user.getRoleIdList().size())
				throw new RRException("该角色不存在");
			
			StringBuilder sb = new StringBuilder();
			boolean isFirst = true;
			for(SysRoleEntity s: list) {
				if (isFirst) {
					isFirst = false;
				} else {
					sb.append(",");
				}
				sb.append(s.getRoleName());
			}
			//user.setRoleList(sb.toString());
		}
			//user.setRoleList("无");
	}

	@Override
	public void resetPwd(Long[] userIds) {
		List<SysUserEntity> users = this.selectBatchIds(Arrays.asList(userIds));
		
		List<SysUserEntity> newUsers = new ArrayList<>();
		for(SysUserEntity user: users) {
			SysUserEntity u = new SysUserEntity();
			u.setUserId(user.getUserId());
			u.setPassword(new Sha256Hash(Constant.ORIGINAL_PASSWORD, user.getSalt(),1024).toHex());
			newUsers.add(u);
		}
		this.updateBatchById(newUsers);
	}
}
